package com.plr.booker;

import java.io.IOException;
import java.io.StringReader;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.NodeList;

public class AC2ULFS_PROD_YLWYYD {

//	static String file = "qwerty.xml";
	static String file = "bugLFS/YLWYYD.xml";

	static EndPoint ep = PROD_END_POINTS.DCLowFareSearchWS;
	/**
	 * Starting point for the SAAJ - SOAP Client Testing
	 */
	public static void main(String args[]) {
		try {
			// Create SOAP Connection
			System.err.println(ep.getEndPoint());
			System.err.println(ep.getMethod());
			SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory
					.newInstance();
			doit(soapConnectionFactory);
		} catch (Exception e) {
			System.err
					.println("Error occurred while sending SOAP Request to Server");
			e.printStackTrace();
		}
	}

	private static void doit(SOAPConnectionFactory soapConnectionFactory)
			throws SOAPException, Exception {

		SOAPConnection soapConnection = null;
		try {
			soapConnection = soapConnectionFactory.createConnection();
			// Send SOAP Message to SOAP Server
			// String url =
			// "http://ws.cdyne.com/emailverify/Emailvernotestemail.asmx";
			SOAPMessage soapResponse = soapConnection.call(
					createSOAPRequestAC2U(), ep.getEndPoint());

			// Process the SOAP Response
			printSOAPResponse(soapResponse);

		} finally {
			if (soapConnection != null) {
				soapConnection.close();
			}
		}
	}

	private static SOAPMessage createSOAPRequestAC2U() throws Exception {
		MessageFactory messageFactory = MessageFactory
				.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
		SOAPMessage soapMessage = messageFactory.createMessage();

		SOAPPart soapPart = soapMessage.getSOAPPart();
		soapPart.getEnvelope().setPrefix("soap");

		// String serverURI = "http://ws.cdyne.com/";
		String serverURI = "http://schemas.xmlsoap.org/soap/envelope/";

		// SOAP Envelope
		SOAPEnvelope envelope = soapPart.getEnvelope();
		envelope.setPrefix("soap");

		envelope.addNamespaceDeclaration("xsi",
				"http://www.w3.org/2001/XMLSchema-instance");
		envelope.addNamespaceDeclaration("xsd",
				"http://www.w3.org/2001/XMLSchema");
		envelope.addNamespaceDeclaration("soap", serverURI);

		/*
		 * POST /20110328/DirectConnect/LowFareSearch/DCLowFareSearchWS.asmx
		 * HTTP/1.1 Host: ws-ac2u.aircanada.com Content-Type: text/xml;
		 * charset=utf-8 Content-Length: length SOAPAction:
		 * "http://www.aircanada.com/ac2u/getACLowFareFlightAvailability"
		 * 
		 * <?xml version="1.0" encoding="utf-8"?> <soap:Envelope
		 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 * xmlns:xsd="http://www.w3.org/2001/XMLSchema"
		 * xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body>
		 * <getACLowFareFlightAvailability
		 * xmlns="http://www.aircanada.com/ac2u/">
		 * <requestXML>string</requestXML> </getACLowFareFlightAvailability>
		 * </soap:Body> </soap:Envelope>
		 */
		envelope.getHeader().setPrefix("soap");
		// SOAP Body
		SOAPBody soapBody = envelope.getBody();
		soapBody.setPrefix("soap");
		SOAPElement soapBodyElem = soapBody.addChildElement(
				 ep.getMethod(), "",
				"http://www.aircanada.com/ac2u/");

		SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("requestXML",
				"");

		String xml = readFile(file, Charset.forName("UTF-8"));
		soapBodyElem1.addTextNode(xml);

		MimeHeaders headers = soapMessage.getMimeHeaders();
		headers.addHeader("SOAPAction",
				"http://www.aircanada.com/ac2u/" + ep.getMethod());

		soapMessage.saveChanges();

		Source sourceContent = soapMessage.getSOAPPart().getContent();

		/* Print the request message */
		System.out.print("Request SOAP Message = ");
		StreamResult result = new StreamResult(System.out);
		TransformerFactory transformerFactory = TransformerFactory
				.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		transformer.setOutputProperty(
				"{http://xml.apache.org/xslt}indent-amount", "2");
		transformer.transform(sourceContent, result);

		soapMessage.writeTo(System.out);
		System.out.println();

		return soapMessage;
	}

	static String readFile(String path, Charset encoding) throws IOException {
		byte[] encoded = Files.readAllBytes(Paths.get(path));
		return encoding.decode(ByteBuffer.wrap(encoded)).toString();
	}


	/**
	 * Method used to print the SOAP Response
	 */
	private static void printSOAPResponse(SOAPMessage soapResponse)
			throws Exception {

		Source sourceContent = soapResponse.getSOAPPart().getContent();
		System.out.print("\nResponse SOAP Message = ");
		StreamResult result = new StreamResult(System.out);
		StreamResult result2 = new StreamResult(System.err);

		TransformerFactory transformerFactory = TransformerFactory
				.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		transformer.setOutputProperty(
				"{http://xml.apache.org/xslt}indent-amount", "2");
		transformer.transform(sourceContent, result);

		System.out.println();

		SOAPBody body = soapResponse.getSOAPBody();
		NodeList nl = body
				.getElementsByTagName(ep.getMethod() + "Result");

		for (int i = 0; i < nl.getLength();) {
			org.w3c.dom.Node n = nl.item(i);

			Source test = new StreamSource(new StringReader(n.getTextContent()));

			transformer.transform(test, result2);
			break;
		}
	}

}
